using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.WowAddonStudio.Lua.RuntimeService.ShellHost;
using Microsoft.WowAddonStudio.Lua.RuntimeService.ToolWindows;
using Microsoft.WowAddonStudio.Lua.RuntimeService.WowBench.Resolvers;
using Microsoft.WowAddonStudio.Services;

namespace Microsoft.WowAddonStudio.Lua.RuntimeService
{
	/// <summary>
	/// Represents a service which responsible for performing Lua Runtime management.
	/// </summary>
	[Guid(GuidStrings.LuaRuntimeService)]
	public class LuaRuntimeService : ILuaRuntimeService, IDisposable
	{
		#region Private Variables

		private readonly IServiceProvider serviceProvider;
		private readonly ILuaRuntime luaRuntime;

		#endregion

		#region Lifecycle Methods

		/// <summary>
		/// Initializes a new instance of the <see cref="LuaRuntimeService"/> class.
		/// </summary>
		/// <param name="provider">The <see cref="IServiceProvider"/> parameter.</param>
		public LuaRuntimeService(IServiceProvider provider)
		{
			serviceProvider = provider;
			luaRuntime = new LuaRuntime(serviceProvider, 
				new ResolverFactory(serviceProvider), new ShellHostFactory());
		}

		#endregion

		#region Properties

		/// <summary>
		/// Defines a mechanism for retrieving a service object;
		/// </summary>
		public IServiceProvider Site
		{
			get { return serviceProvider; }
		}

		/// <summary>
		/// Gets the <see cref="LuaRuntime"/> object.
		/// </summary>
		public ILuaRuntime LuaRuntime
		{
			get { return luaRuntime; }
		}

		#endregion

		#region ILuaRuntimeService Members

		/// <summary>
		/// Called when the user clicks the menu item that shows the tool window.
		/// </summary>
		public void ShowWowBenchToolWindow()
		{
			try
			{
				var window = (WowBenchToolWindow) serviceProvider.GetService(typeof (WowBenchToolWindow));
				var windowFrame = (IVsWindowFrame) window.Frame;
				ErrorHandler.ThrowOnFailure(windowFrame.Show());
			}
			catch (Exception ex)
			{
				Trace.WriteLine(String.Concat("WoWBench ShowToolWindow exception:\n", ex));
			}
		}

		/// <summary>
		/// Adds and loads lua code file into runtime.
		/// </summary>
		/// <param name="filePath">The path to the lua file.</param>
		public void AddLuaFile(string filePath)
		{
			LuaRuntime.AddLuaFile(filePath);
		}

		/// <summary>
		/// Removes and unloads lua code file from runtime.
		/// </summary>
		/// <param name="filePath">The path to the lua file.</param>
		public void RemoveLuaFile(string filePath)
		{
			LuaRuntime.RemoveLuaFile(filePath);
		}

		/// <summary>
		/// Evaluates a lua expression in the context of the current Lua runtime.
		/// </summary>
		/// <param name="luaExpression">The lua expression to evaluate.</param>
		/// <returns>The return value of the evaluated expression.</returns>
		public object EvaluateExpression(string luaExpression)
		{
			return LuaRuntime.EvaluateExpression(luaExpression);
		}

		#endregion

		#region IDisposable Members


		/// <summary>
		/// Performs application-defined tasks associated with freeing,
		/// releasing, or resetting unmanaged resources.
		/// </summary>
		public void Dispose()
		{
			if(luaRuntime != null)
				luaRuntime.Dispose();
		}

		#endregion

	}
}